package com.ruoyi.client.service.impl;


import com.ruoyi.client.domain.vo.request.ClientEventApplyRequestVo;
import com.ruoyi.client.domain.vo.response.ClientEventDetailResponseVo;
import com.ruoyi.client.mapper.ClientEventApplyMapper;
import com.ruoyi.client.mapper.ClientUserTMapper;
import com.ruoyi.client.service.IEventApplyService;
import com.ruoyi.common.core.domain.entity.EventApply;
import com.ruoyi.common.core.domain.entity.EventDetail;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * 活动报名Service业务层处理
 * 
 * @author xukai
 * @date 2024-11-11
 */
@Service
public class ClientEventApplyServiceImpl implements IEventApplyService
{
    @Autowired
    private ClientEventApplyMapper eventApplyMapper;

    @Autowired
    private ClientUserTMapper userTMapper;

    @Override
    @Transactional
    public int apply(ClientEventApplyRequestVo requestVo) {
        // 1.判断用户是否已经报名
        Integer applyCount = eventApplyMapper.getEventApply(requestVo.getUserId(), requestVo.getEventId());
        // 2.如果已经报名，返回报名失败，返回-1
        if(applyCount > 0){
            return -1;
        }
        // 3.如果未报名，先判断活动名额是否已满
        else{
            // 3.1 查询活动
            EventDetail eventDetail = eventApplyMapper.getEventDetail(requestVo.getEventId());
            
            // 3.2.如果活动名额已满，返回报名失败，返回-2
            if(eventDetail.getRemain() <= 0){
                return -2;
            }
            
            // 使用工具类判断是否可以报名
            boolean hasApplied = false;
            if(!com.ruoyi.common.utils.ApplyStatusUtils.canApply(eventDetail, hasApplied)) {
                // 判断具体原因
                com.ruoyi.common.enums.ApplyStatusEnum status = com.ruoyi.common.utils.ApplyStatusUtils.getApplyStatus(eventDetail, hasApplied);
                if(status == com.ruoyi.common.enums.ApplyStatusEnum.NOT_STARTED) {
                    return -3; // 活动报名未开始
                } else if(status == com.ruoyi.common.enums.ApplyStatusEnum.ENDED) {
                    return -4; // 活动报名已结束
                }
                return -5; // 其他原因
            }
            
            // 3.3.如果活动名额未满，进行报名操作
            // 3.3.1.更新活动名额
            int i = eventApplyMapper.reduceRemain(requestVo.getEventId());
            // 3.3.3.插入报名记录
            EventApply eventApply = new EventApply();
            eventApply.setUserId(requestVo.getUserId());
            eventApply.setEventId((long) requestVo.getEventId());
            eventApply.setApplyTime(new Date());
            eventApply.setCreatedAt(new Date());
            eventApply.setUpdatedAt(new Date());
            eventApply.setPhone(requestVo.getPhone());
            eventApply.setUserName(requestVo.getUserName());
            eventApplyMapper.insertEventApply(eventApply);
            return 1;
        }
    }

    @Override
    public List<EventDetail> getUnBeginEvent(String userId) {
        // 1.查询用户已报名且未开始的活动
        return  eventApplyMapper.getUnBeginEvent(userId);
    }

    @Override
    @Transactional
    public int cancelApply(String userId, Integer eventId) {
        // 1.取消报名
        int i = eventApplyMapper.cancelApply(userId, eventId);
        // 2.如果取消成功，更新活动名额
        if(i !=0 ){
            eventApplyMapper.addRemain(eventId);
        }
        return i;


    }

    @Override
    public List<EventDetail> getUnSignInEvent(String userId) {
        // 1.获取未签到的活动
        return eventApplyMapper.getUnSignInEvent(userId);
    }

    @Override
    public List<EventDetail> getEventList() {
        // 1.获取活动列表
        return eventApplyMapper.getEventList();
    }

    @Override
    public ClientEventDetailResponseVo getEventDetail(Integer eventId, String userId) {
        // 1.获取活动详情
        EventDetail eventDetail = eventApplyMapper.getEventDetail(eventId);
        // 2.判断用户是否报名
        Integer applyCount = eventApplyMapper.getEventApply(userId, eventId);
        ClientEventDetailResponseVo clientEventDetailResponseVo = new ClientEventDetailResponseVo();
        //复制属性，使用BeanUtils.copyProperties(eventDetail, clientRewardIndexResponseVo);
        BeanUtils.copyProperties(eventDetail, clientEventDetailResponseVo);
        
        // 使用工具类设置报名状态
        boolean hasApplied = applyCount > 0;
        com.ruoyi.common.utils.ApplyStatusUtils.setApplyStatus(clientEventDetailResponseVo, hasApplied, "applyStatus");
        
        return clientEventDetailResponseVo;
    }

    @Override
    public List<EventDetail> getUnSignOutEvent(String userId) {
        // 1.获取未签退的活动
        return eventApplyMapper.getUnSignOutEvent(userId);
    }

    @Override
    public int signIn(String userId, Integer eventId, String code) {
        // 1.校验签到码是否正确
        EventDetail eventDetail = eventApplyMapper.getEventDetail(eventId);
        if(!code.equals(eventDetail.getSignInCode())){
            return -1;
        }
        // 2.校验是否处于签到时间内，需要在活动进行中的时候可以签到
        Date currentDate = new Date();
        // 2.1 如果不处于签到时间，返回-2
        if(currentDate.before(eventDetail.getEventBegin()) || currentDate.after(eventDetail.getEventEnd())){
            return -2;
        }
        // 2.2 如果处于签到时间，更新签到状态
        return eventApplyMapper.signIn(userId, eventId);
    }

    @Override
    @Transactional
    public int signOut(String userId, Integer eventId, String code) {
        // 1.校验签退码是否正确
        EventDetail eventDetail = eventApplyMapper.getEventDetail(eventId);
        if(!code.equals(eventDetail.getSignOutCode())){
            return -1;
        }
        // 2.校验是否处于签退时间内，需要在活动进行中的时候可以签退
        Date currentDate = new Date();
        // 2.1 在活动开始到活动结束两个小时内可以签退
        // 获取活动结束后的两个小时的时间,转成date类型
        long time = eventDetail.getEventEnd().getTime() + 2*60*60*1000;
        Date signOutDeadLine = new Date(time);
        if(currentDate.after(signOutDeadLine)||currentDate.before(eventDetail.getEventBegin())){
            return -2;
        }
        // 2.2 如果处于签退时间，更新签退状态
        int i = eventApplyMapper.signOut(userId, eventId);
        // 3.签退成功,则给用户加积分
        if(i == 1){
            // 3.1 获取活动积分数量
            Long credit = eventDetail.getCredit();
            // 3.2 更新用户积分
            userTMapper.updateUserCredit(userId, credit.intValue());
        }
        return 1;
    }

    @Override
    public List<EventDetail> getFinishedEvent(String userId) {
        // 1.获取已完成的活动
        return eventApplyMapper.getFinishedEvent(userId);
    }
}
